from flask import Flask, request, jsonify, send_file
import os
from datetime import datetime
from pygments import highlight
from pygments.formatters import ImageFormatter
from pygments.lexers import get_lexer_by_name
import re
import requests
import shutil

app = Flask(__name__)

# 配置保存目录
MARKDOWN_DIR = "D:\\code\\PycharmProjects\\content2file\\markdown_files"
IMAGE_DIR = "D:\\code\\PycharmProjects\\content2file\\image_files"

# 确保保存目录存在
for dir_path in [MARKDOWN_DIR, IMAGE_DIR]:
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)

def extract_code_blocks(markdown_text):
    """从Markdown文本中提取代码块，但排除mermaid"""
    # 匹配 ```language\n code \n``` 格式的代码块
    pattern = r'```(\w+)\n(.*?)\n```'
    matches = re.finditer(pattern, markdown_text, re.DOTALL)
    code_blocks = []
    
    for match in matches:
        language = match.group(1)
        # 跳过mermaid代码块
        if language.lower() == 'mermaid':
            continue
        code = match.group(2).strip()
        code_blocks.append({
            'language': language,
            'code': code
        })
    
    return code_blocks

def translate_with_glm4(text):
    """使用GLM-4翻译文本"""
    try:
        url = "http://your-one-api:3000/v1/chat/completions"
        headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer sk-key"  # 请替换为你的API密钥
        }
        
        # 构建翻译提示
        prompt = f"请将以下中文翻译为英文，只返回翻译结果，不要有任何其他解释：\n{text}"
        
        data = {
            "model": "glm-4-flash",
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.7
        }
        
        response = requests.post(url, headers=headers, json=data)
        if response.status_code == 200:
            result = response.json()
            # 从响应中提取翻译结果
            translated_text = result['choices'][0]['message']['content'].strip()
            return translated_text
        else:
            print(f"翻译请求失败: {response.status_code}")
            return text
    except Exception as e:
        print(f"翻译过程出错: {str(e)}")
        return text

def translate_chinese_in_code(code):
    """将代码中的中文注释和字符串翻译成英文"""
    try:
        # 匹配中文字符的正则表达式
        chinese_pattern = r'[一-龥]+'
        
        # 查找所有包含中文的行
        lines = code.split('\n')
        for i, line in enumerate(lines):
            # 查找该行中的所有中文
            if re.search(chinese_pattern, line):
                # 对整行进行翻译
                translated_line = translate_with_glm4(line)
                lines[i] = translated_line
        
        # 重新组合代码
        translated_code = '\n'.join(lines)
        return translated_code
    except Exception as e:
        print(f"翻译过程出错: {str(e)}")
        return code  # 如果翻译失败，返回原始代码

def code_to_image(code, language='python', line_numbers=True):
    try:
        # 先翻译代码中的中文
        translated_code = translate_chinese_in_code(code)
        
        # 处理特殊语言
        if language.lower() == 'vue':
            language = 'html'  # 或者使用 'javascript'，取决于内容
            
        lexer = get_lexer_by_name(language)
        formatter = ImageFormatter(
            font_size=20,
            line_numbers=line_numbers,
            line_number_bg='#eeeeee',
            style='monokai',
            line_number_chars=3
        )
        
        image_bytes = highlight(translated_code, lexer, formatter)
        return image_bytes
    except Exception as e:
        print(f"生成图片时出错: {str(e)}")
        return None

def replace_code_blocks_with_images(markdown_text, image_results):
    """将代码块替换为对应的图片链接，但保留mermaid"""
    current_block = 0
    def replace_match(match):
        nonlocal current_block
        language = match.group(1)
        # 如果是mermaid代码块，保持原样
        if language.lower() == 'mermaid':
            return match.group(0)
        
        if current_block < len(image_results):
            image_filename = image_results[current_block]['image_filename']
            replacement = f"\n![code](../image_files/{image_filename})\n"
            current_block += 1
            return replacement
        return match.group(0)
    
    # 替换代码块为图片链接
    pattern = r'```(\w+)\n(.*?)\n```'
    result = re.sub(pattern, replace_match, markdown_text, flags=re.DOTALL)
    return result

@app.route('/convert-md-code', methods=['POST'])
def convert_md_code():
    try:
        data = request.get_json()
        
        if not data or 'filename' not in data:
            return jsonify({'error': '需要提供markdown文件名'}), 400
        
        # 获取文件名并确保有.md后缀
        filename = data['filename']
        if not filename.endswith('.md'):
            filename += '.md'
        
        # 构建文件路径并检查文件是否存在
        file_path = os.path.join(MARKDOWN_DIR, filename)
        if not os.path.exists(file_path):
            return jsonify({'error': '文件不存在'}), 404
            
        # 读取文件内容
        with open(file_path, 'r', encoding='utf-8') as f:
            markdown_text = f.read()
        
        # 提取代码块
        code_blocks = extract_code_blocks(markdown_text)
        
        if not code_blocks:
            return jsonify({'message': '文件中未找到代码块'}), 200
        
        # 生成图片并保存I
        results = []
        
        for index, block in enumerate(code_blocks):
            image_bytes = code_to_image(
                block['code'], 
                block['language']
            )
            
            if image_bytes:
                image_filename = f"{filename.rsplit('.', 1)[0]}_{index+1}.png"
                image_path = os.path.join(IMAGE_DIR, image_filename)
                
                with open(image_path, 'wb') as f:
                    f.write(image_bytes)
                
                results.append({
                    'language': block['language'],
                    'image_filename': image_filename
                })
        
        # 替换原文件中的代码块为图片链接
        new_content = replace_code_blocks_with_images(markdown_text, results)
        
        # 保存更新后的markdown文件
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(new_content)
        
        return jsonify({
            'message': '代码块已转换为图片并更新文件',
            'total_blocks': len(code_blocks),
            'converted_images': results
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/save-text', methods=['POST'])
def save_text():
    try:
        data = request.get_json()
        
        if not data or 'text' not in data:
            return jsonify({'error': '没有提供文本内容'}), 400
            
        text_content = data['text']
        
        # 检查是否提供了文件名
        if 'filename' in data:
            filename = data['filename']
            if not filename.endswith('.md'):
                filename += '.md'
        else:
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            filename = f"text_{timestamp}.md"
        
        # 保存markdown文件
        file_path = os.path.join(MARKDOWN_DIR, filename)
        mode = 'a' if os.path.exists(file_path) else 'w'
        with open(file_path, mode, encoding='utf-8') as f:
            if mode == 'a':
                f.write('\n\n')
            f.write(text_content)
        
        # 如果定要生成图片
        if data.get('generate_image', False):
            # 获取代码语言，默认为python
            language = data.get('language', 'python')
            
            # 生成图片
            image_bytes = code_to_image(text_content, language)
            if image_bytes:
                # 保存图片
                image_filename = filename.rsplit('.', 1)[0] + '.png'
                image_path = os.path.join(IMAGE_DIR, image_filename)
                with open(image_path, 'wb') as f:
                    f.write(image_bytes)
                
                return jsonify({
                    'message': 'You finished it!!',
                    'filename': filename,
                    'mode': 'added' if mode == 'a' else 'created',
                    'image': image_filename
                }), 200
            
        return jsonify({
            'message': 'You finished it!!',
            'filename': filename,
            'mode': 'added' if mode == 'a' else 'created'
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/duplicate-file', methods=['POST'])
def duplicate_file():
    try:
        data = request.get_json()
        
        if not data or 'filename' not in data or 'copies' not in data:
            return jsonify({'error': '需要提供原文件名和复制份数'}), 400
            
        filename = data['filename']
        copies = int(data['copies'])
        
        if copies <= 0:
            return jsonify({'error': '复制份数必须大于0'}), 400
            
        # 构建原文件路径并检查文件是否存在
        original_file = os.path.join(MARKDOWN_DIR, filename)
        if not os.path.exists(original_file):
            return jsonify({'error': '原文件不存在'}), 404
            
        # 获取文件名和扩展名
        name, ext = os.path.splitext(filename)
        
        # 复制文件
        copied_files = []
        for i in range(1, copies + 1):
            new_filename = f"{name}_{i}{ext}"
            new_filepath = os.path.join(MARKDOWN_DIR, new_filename)
            
            # 复制文件
            shutil.copy2(original_file, new_filepath)
            copied_files.append(new_filename)
        
        return jsonify({
            'message': f'成功复制 {copies} 份文件',
            'original_file': filename,
            'copied_files': copied_files
        }), 200
        
    except ValueError:
        return jsonify({'error': '复制份数必须是有效的整数'}), 400
    except Exception as e:
        return jsonify({'error': str(e)}), 500



@app.route('/convert-to-text/<path:filename>', methods=['GET'])
def convert_to_text(filename):
    try:
        # 根据文件扩展名判断从哪个目录获取文件
        if filename.endswith(('.md', '.txt')):
            file_path = os.path.join(MARKDOWN_DIR, filename)
        elif filename.endswith(('.png', '.jpg', '.jpeg')):
            file_path = os.path.join(IMAGE_DIR, filename)
        else:
            return jsonify({'error': '不支持的文件类型'}), 400
            
        if not os.path.exists(file_path):
            return jsonify({'error': '文件不存在'}), 404
            
        # 读取文件内容
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
            
        # 直接返回处理好的格式
        return content.replace('\n', '\r\n'), 200, {'Content-Type': 'text/plain; charset=utf-8'}
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)



